#include "Test.hpp"
#include "../Real.hpp"
#include <iostream>
#include <string>
using namespace std;

// Test de truncamiento
bool test_truncamiento()
{
	TEST_START();

	// asegura de que no redondee el número
	Real::roundNumber = false;

	double n[53];
	double e = 2;

	// calcula números con exponente n[0] con 0 a 52 dígitos de mantisa
	n[0] = 2;
	for( int i = 1 ; i <= 52 ; i++ )
	{
		n[i] = n[i-1]+n[0]/e;
		e   *= 2;
	}

	// verifica que truncar el número con 52 unos en la mantisa sea
	// lo mismo que su correspondiente calculado
	for( int i = 0 ; i <= 52 ; i++ )
	{
		Real::precision(i);
		TEST_EQ( Real(n[52]).toDouble(), n[i] );
	}

	TEST_END();
}

// Test de redondeo
// (!) depende del test de truncamiento
bool test_redondeo()
{
	TEST_START();

	// asegura de que redondee el número
	Real::roundNumber = true;

	double n[53];
	double e = 2;

	// calcula números con exponente n[0] con 0 a 52 dígitos de mantisa
	n[0] = 2;
	for( int i = 1 ; i <= 52 ; i++ )
	{
		n[i] = n[i-1]+n[0]/e;
		e   *= 2;
	}

	// rendondea el número con 52 unos en la mantisa al próximo exponente
	for( int i = 0 ; i <= 51 ; i++ )
	{
		Real::precision(i);
		TEST_EQ( Real(n[52]).toDouble(), n[0]*2 );
	}

	// rendondea números que no tienen que aumentar el exponente
	double k = n[52]-n[0]/2;
	for( int i = 2 ; i <= 51 ; i++ )
	{
		Real::precision(i);
		TEST_EQ( Real(k).toDouble(), n[1] );
	}

	// al tener 52 dígitos de precisión no redondea
	Real::precision(52);
	TEST_EQ( Real(n[52]).toDouble(), n[52] );
	
	TEST_END();
}

Test tests[] = {
	TEST(test_truncamiento), 
	TEST(test_redondeo) 
};

int tests_count  = 2;
int tests_failed = 0;

int main()
{
	
	for( int i = 0 ; i < tests_count ; i++ )
	{
		cout << "Corriendo test: " << tests[i].name << endl;
		if( !tests[i].test() )
			tests_failed++;
	}

	cout << tests_count << " tests: " 
	     << tests_count-tests_failed << " pasados, "
	     << tests_failed << " fallaron." << endl;

	return 0;
}

